package com._54programer.demo1;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/*
服务端输出:
服务器线程名: nioEventLoopGroup-3-1
ctx: ChannelHandlerContext(NettyServerHandler#0, [id: 0x21078780, L:/127.0.0.1:10000 - R:/127.0.0.1:57375])
客户端消息: hello server
客户端地址: /127.0.0.1:57375
 */
public class NettyServer {
    public static void main(String[] args) throws Exception {
        /**
         * 创建两个线程组bossGroup和workerGroup, 都是无线循环
         * bossGroup只负责连接请求
         * workerGroup负责处理客户端业务
         * 两个线程组包含的子线程个数: 默认是cpu核数 * 2
         */
        //1.创建线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //2.创建服务器端启动对象, 并配置参数
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)//使用NioServerSocketChannel作为服务器的通道实现
                    .option(ChannelOption.SO_BACKLOG, 128) //设置线程队列的连接个数
                    .childOption(ChannelOption.SO_KEEPALIVE, true) //设置保持活动连接状态
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) throws Exception {

                            //可以使用一个集合管理SocketChannel, 在推送消息的时候, 将业务添加到各个channel对应的NIOEventLoop的taskQueue或scheduleTaskQueue中
                            System.out.println("客户端channel: "+socketChannel.hashCode());

                            //5.给pipeline设置处理器
                            socketChannel.pipeline().addLast(new NettyServerHandler());
                        }
                    });
            //3.绑定一个端口并且同步, 生成一个ChannelFuture对象
            ChannelFuture cf = bootstrap.bind(10000).sync();
            //4.对关闭通道进行监听
            cf.channel().closeFuture().sync();
        } finally {
            //6.优雅的关闭
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
